﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

// Содержит устаревшую реализацию для программного интерфейса модуля АдминистрированиеКластераКлиентСервер.

#Если Не ВебКлиент И НЕ МобильныйКлиент Тогда

#Область СлужебныйПрограммныйИнтерфейс

#Область БлокировкаСеансовИЗаданий

// Возвращает текущее состояние блокировки сеансов и регламентных заданий для информационной базы.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//
// Возвращаемое значение:
//   см. АдминистрированиеКластераКлиентСервер.СвойстваБлокировкиСеансовИРегламентныхЗаданий
//
Функция БлокировкаСеансовИЗаданийИнформационнойБазы(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ) Экспорт
	
	Результат = СвойстваИнформационнойБазы(ПараметрыАдминистрированияКластера, ПараметрыАдминистрированияИБ, СловарьСвойствБлокировкиСеансовИРегламентныхЗаданий());
	
	Если Результат.ДатаС = АдминистрированиеКластераКлиентСервер.ПустаяДата() Тогда
		Результат.ДатаС = Неопределено;
	КонецЕсли;
	
	Если Результат.ДатаПо = АдминистрированиеКластераКлиентСервер.ПустаяДата() Тогда
		Результат.ДатаПо = Неопределено;
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(Результат.КодРазрешения) Тогда
		Результат.КодРазрешения = "";
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(Результат.Сообщение) Тогда
		Результат.Сообщение = "";
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(Результат.ПараметрБлокировки) Тогда
		Результат.ПараметрБлокировки = "";
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

// Устанавливает новое состояние блокировки сеансов и регламентных заданий для информационной базы.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//  СвойстваБлокировкиСеансовИЗаданий - см. АдминистрированиеКластераКлиентСервер.СвойстваБлокировкиСеансовИРегламентныхЗаданий
//
Процедура УстановитьБлокировкуСеансовИЗаданийИнформационнойБазы(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ, Знач СвойстваБлокировкиСеансовИЗаданий) Экспорт
	
	УстановитьСвойстваИнформационнойБазы(
		ПараметрыАдминистрированияКластера,
		ПараметрыАдминистрированияИБ,
		СловарьСвойствБлокировкиСеансовИРегламентныхЗаданий(),
		СвойстваБлокировкиСеансовИЗаданий);
	
КонецПроцедуры

// Проверяет корректность параметров администрирования.
//
// Параметр ПараметрыАдминистрированияИБ может быть опущен в том случае, если аналогичные поля были указаны в структуре,
// переданной в качестве значения параметра ПараметрыАдминистрированияКластера.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//  ПроверятьПараметрыАдминистрированияКластера - Булево - флаг необходимости проверки параметров администрирования 
//                                                кластера
//  ПроверятьПараметрыАдминистрированияИнформационнойБазы - Булево - флаг необходимости проверки параметров
//                                                          администрирования кластера.
//
Процедура ПроверитьПараметрыАдминистрирования(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ = Неопределено,
	ПроверятьПараметрыАдминистрированияИнформационнойБазы = Истина,
	ПроверятьПараметрыАдминистрированияКластера = Истина) Экспорт
	
	
	Если ПроверятьПараметрыАдминистрированияКластера Или ПроверятьПараметрыАдминистрированияИнформационнойБазы Тогда
		
		ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
		СвойстваРабочихПроцессов(ИдентификаторКластера, ПараметрыАдминистрированияКластера);
		
	КонецЕсли;
	
	Если ПроверятьПараметрыАдминистрированияИнформационнойБазы Тогда
		
		Словарь = Новый Структура();
		Словарь.Вставить("БлокировкаСеансов", "sessions-deny");
		
		СвойстваИнформационнойБазы(ПараметрыАдминистрированияКластера, ПараметрыАдминистрированияИБ, Словарь);
		
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область БлокировкаРегламентныхЗаданий

// Возвращает текущее состояние блокировки регламентных заданий для информационной базы.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//
// Возвращаемое значение:
//   Булево
//
Функция БлокировкаРегламентныхЗаданийИнформационнойБазы(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ) Экспорт
	
	Словарь = Новый Структура("БлокировкаЗаданий", "scheduled-jobs-deny");
	
	СвойстваИБ = СвойстваИнформационнойБазы(ПараметрыАдминистрированияКластера, ПараметрыАдминистрированияИБ, Словарь);
	Возврат СвойстваИБ.БлокировкаЗаданий;
	
КонецФункции

// Устанавливает новое состояние блокировки регламентных заданий для информационной базы.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//  БлокировкаРегламентныхЗаданий - Булево - флаг установки блокировки регламентных заданий информационной базы.
//
Процедура УстановитьБлокировкуРегламентныхЗаданийИнформационнойБазы(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ, Знач БлокировкаРегламентныхЗаданий) Экспорт
	
	Словарь = Новый Структура("БлокировкаЗаданий", "scheduled-jobs-deny");
	Свойства = Новый Структура("БлокировкаЗаданий", БлокировкаРегламентныхЗаданий);
	
	УстановитьСвойстваИнформационнойБазы(
		ПараметрыАдминистрированияКластера,
		ПараметрыАдминистрированияИБ,
		Словарь,
		Свойства);
	
КонецПроцедуры

#КонецОбласти

#Область СеансыИнформационнойБазы

// Возвращает описания сеансов информационной базы.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//  Фильтр - см. АдминистрированиеКластера.ФильтрСеансов, Массив из см. АдминистрированиеКластера.ФильтрСеансов
//
// Возвращаемое значение:
//   Массив из см. АдминистрированиеКластераКлиентСервер.СвойстваСеанса
//
Функция СеансыИнформационнойБазы(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ, Знач Фильтр = Неопределено) Экспорт
	
	ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
	ИдентификаторИнформационнойБазы = ИдентификаторИнформационнойБазы(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ПараметрыАдминистрированияИБ);
	Возврат СвойстваСеансов(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИдентификаторИнформационнойБазы, Фильтр);
	
КонецФункции

// Удаляет сеансы с информационной базой по фильтру.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//  Фильтр - см. АдминистрированиеКластера.ФильтрСеансов, Массив из см. АдминистрированиеКластера.ФильтрСеансов
//
Процедура УдалитьСеансыИнформационнойБазы(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ, Знач Фильтр = Неопределено) Экспорт
	
	Шаблон = "%rac session --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% terminate --session=%session%";
	
	Параметры = Новый Соответствие();
	
	ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	
	ИдентификаторИнформационнойБазы = ИдентификаторИнформационнойБазы(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ПараметрыАдминистрированияИБ);
	
	КоличествоПопыток = 3;
	ВсеСеансыУдалены = Ложь;
	
	Для ТекущаяПопытка = 0 По КоличествоПопыток Цикл
		
		Сеансы = СвойстваСеансов(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИдентификаторИнформационнойБазы, Фильтр, Ложь);
		
		Если Сеансы.Количество() = 0 Тогда
			
			ВсеСеансыУдалены = Истина;
			Прервать;
			
		ИначеЕсли ТекущаяПопытка = КоличествоПопыток Тогда
			
			Прервать;
			
		КонецЕсли;
		
		Для каждого Сеанс Из Сеансы Цикл
			
			Попытка
				
				Параметры.Вставить("session", Сеанс.Получить("session"));
				ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
				
			Исключение
				
				// Сеанс мог завершиться к моменту вызова rac session terminate.
				Продолжить;
				
			КонецПопытки;
			
		КонецЦикла;
		
	КонецЦикла;
	
	Если НЕ ВсеСеансыУдалены Тогда
	
		ВызватьИсключение НСтр("ru = 'Не удалось удалить сеансы.'");
		
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область СоединенияСИнформационнойБазой

// Возвращает описания соединений с информационной базой.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//  Фильтр - см. АдминистрированиеКластера.ФильтрСоединений, Массив из см. АдминистрированиеКластера.ФильтрСоединений
//
// Возвращаемое значение:
//   Массив из см. АдминистрированиеКластераКлиентСервер.СвойстваСоединения
//
Функция СоединенияСИнформационнойБазой(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ, Знач Фильтр = Неопределено) Экспорт
	
	ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
	ИдентификаторИнформационнойБазы = ИдентификаторИнформационнойБазы(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ПараметрыАдминистрированияИБ);
	Возврат СвойстваСоединений(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИдентификаторИнформационнойБазы, ПараметрыАдминистрированияИБ, Фильтр, Истина);
	
КонецФункции

// Разрывает соединения с информационной базой по фильтру.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//  Фильтр - см. АдминистрированиеКластера.ФильтрСоединений, Массив из см. АдминистрированиеКластера.ФильтрСоединений
//
Процедура РазорватьСоединенияСИнформационнойБазой(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ, Знач Фильтр = Неопределено) Экспорт
	
	Шаблон = "%rac connection --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% disconnect --process=%process% --connection=%connection% --infobase-user=%?infobase-user% --infobase-pwd=%?infobase-pwd%";
	
	Параметры = Новый Соответствие();
	
	ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	
	ИдентификаторИнформационнойБазы = ИдентификаторИнформационнойБазы(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ПараметрыАдминистрированияИБ);
	Параметры.Вставить("infobase", ИдентификаторИнформационнойБазы);
	ЗаполнитьПараметрыАутентификацииВИБ(ПараметрыАдминистрированияИБ, Параметры);
	
	Значение = Новый Массив;
	Значение.Добавить("1CV8");               // идентификатор приложения 1С:Предприятие в режиме запуска "Толстый клиент".
	Значение.Добавить("1CV8C");              // идентификатор приложения 1С:Предприятие в режиме запуска "Тонкий клиент".
	Значение.Добавить("WebClient");          // идентификатор приложения 1С:Предприятие в режиме запуска "Веб-клиент".
	Значение.Добавить("Designer");           // идентификатор приложения Конфигуратор.
	Значение.Добавить("COMConnection");      // идентификатор сессии внешнего соединения 1С:Предприятия через COM.
	Значение.Добавить("WSConnection");       // идентификатор сессии Web-сервиса.
	Значение.Добавить("BackgroundJob");      // идентификатор сессии обработки заданий.
	Значение.Добавить("WebServerExtension"); // идентификатор расширения Web-сервера.

	АдминистрированиеКластераКлиентСервер.ДобавитьУсловиеФильтра(Фильтр, "ИдентификаторКлиентскогоПриложения", ВидСравнения.ВСписке, Значение);
	
	КоличествоПопыток = 3;
	ВсеСоединенияРазорваны = Ложь;
	
	Для ТекущаяПопытка = 0 По КоличествоПопыток Цикл
	
		Соединения = СвойстваСоединений(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИдентификаторИнформационнойБазы, ПараметрыАдминистрированияИБ, Фильтр, Ложь);
		
		Если Соединения.Количество() = 0 Тогда
			
			ВсеСоединенияРазорваны = Истина;
			Прервать;
			
		ИначеЕсли ТекущаяПопытка = КоличествоПопыток Тогда
			
			Прервать;
			
		КонецЕсли;
	
		Для каждого Соединение Из Соединения Цикл
			
			Попытка
				
				Параметры.Вставить("process", Соединение.Получить("process"));
				Параметры.Вставить("connection", Соединение.Получить("connection"));
				ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
				
			Исключение
				
				// Соединение могло уже завершиться к моменту вызова rac connection disconnect.
				Продолжить;
				
			КонецПопытки;
			
		КонецЦикла;
		
	КонецЦикла;
	
	Если НЕ ВсеСоединенияРазорваны Тогда
	
		ВызватьИсключение НСтр("ru = 'Не удалось разорвать соединения.'");
		
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ПрофилиБезопасности

// Возвращает имя профиля безопасности, назначенного для информационной базы.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//
// Возвращаемое значение:
//   Строка - имя профиля безопасности, назначенного для информационной базы. Если
//  для информационной базы не назначен профиль безопасности - возвращается пустая строка.
//
Функция ПрофильБезопасностиИнформационнойБазы(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ) Экспорт
	
	Словарь = Новый Структура();
	Словарь.Вставить("ИмяПрофиля", "security-profile-name");
	
	Результат = СвойстваИнформационнойБазы(ПараметрыАдминистрированияКластера, ПараметрыАдминистрированияИБ, Словарь).ИмяПрофиля;
	Если ЗначениеЗаполнено(Результат) Тогда
		Возврат Результат;
	Иначе
		Возврат "";
	КонецЕсли;
	
КонецФункции

// Возвращает имя профиля безопасности, назначенного для информационной базы в качестве профиля безопасности
//  безопасного режима.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//
// Возвращаемое значение:
//   Строка - имя профиля безопасности, назначенного для информационной базы в качестве профиля
//  безопасности безопасного режима. Если для информационной базы не назначен профиль безопасности - возвращается
//  пустая строка.
//
Функция ПрофильБезопасностиБезопасногоРежимаИнформационнойБазы(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ) Экспорт
	
	Словарь = Новый Структура();
	Словарь.Вставить("ИмяПрофиля", "safe-mode-security-profile-name");
	
	Результат = СвойстваИнформационнойБазы(ПараметрыАдминистрированияКластера, ПараметрыАдминистрированияИБ, Словарь).ИмяПрофиля;
	Если ЗначениеЗаполнено(Результат) Тогда
		Возврат Результат;
	Иначе
		Возврат "";
	КонецЕсли;
	
КонецФункции

// Назначает для информационной базы использование профиля безопасности.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//  ИмяПрофиля - Строка - имя профиля безопасности. Если передана пустая строка - для информационной базы будет
//    отключено использование профиля безопасности.
//
Процедура УстановитьПрофильБезопасностиИнформационнойБазы(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ, Знач ИмяПрофиля = "") Экспорт
	
	Словарь = Новый Структура();
	Словарь.Вставить("ИмяПрофиля", "security-profile-name");
	
	Значения = Новый Структура();
	Значения.Вставить("ИмяПрофиля", ИмяПрофиля);
	
	УстановитьСвойстваИнформационнойБазы(
		ПараметрыАдминистрированияКластера,
		ПараметрыАдминистрированияИБ,
		Словарь,
		Значения);
	
КонецПроцедуры

// Назначает для информационной базы использование профиля безопасности безопасного режима.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИБ - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//  ИмяПрофиля - Строка - имя профиля безопасности. Если передана пустая строка - для информационной базы будет
//    отключено использование профиля безопасности безопасного режима.
//
Процедура УстановитьПрофильБезопасностиБезопасногоРежимаИнформационнойБазы(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ, Знач ИмяПрофиля = "") Экспорт
	
	Словарь = Новый Структура();
	Словарь.Вставить("ИмяПрофиля", "safe-mode-security-profile-name");
	
	Значения = Новый Структура();
	Значения.Вставить("ИмяПрофиля", ИмяПрофиля);
	
	УстановитьСвойстваИнформационнойБазы(
		ПараметрыАдминистрированияКластера,
		ПараметрыАдминистрированияИБ,
		Словарь,
		Значения);
	
КонецПроцедуры

// Проверяет существование в кластере серверов профиля безопасности.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ИмяПрофиля - Строка - имя профиля безопасности, существование которого проверяется.
//
Функция ПрофильБезопасностиСуществует(Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля) Экспорт
	
	Фильтр = Новый Структура("Имя", ИмяПрофиля);
	
	ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
	
	ПрофилиБезопасности = ПолучитьПрофилиБезопасности(ИдентификаторКластера, ПараметрыАдминистрированияКластера, Фильтр);
	
	Возврат (ПрофилиБезопасности.Количество() = 1);
	
КонецФункции

// Возвращает свойства профиля безопасности.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ИмяПрофиля - Строка - имя профиля безопасности.
//
// Возвращаемое значение:
//   см. АдминистрированиеКластераКлиентСервер.СвойстваПрофиляБезопасности
//
Функция ПрофильБезопасности(Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля) Экспорт
	
	Фильтр = Новый Структура("Имя", ИмяПрофиля);
	
	ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
	
	ПрофилиБезопасности = ПолучитьПрофилиБезопасности(ИдентификаторКластера, ПараметрыАдминистрированияКластера, Фильтр);
	
	Если ПрофилиБезопасности.Количество() <> 1 Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'В кластере серверов %1 не зарегистрирован профиль безопасности %2.'"), ИдентификаторКластера, ИмяПрофиля);
	КонецЕсли;
	
	Результат = ПрофилиБезопасности[0];
	Результат = ПреобразоватьЗначенияСвойствИспользованияСписковДоступа(Результат);
	
	// Виртуальный каталоги
	Результат.Вставить("ВиртуальныеКаталоги",
		ПолучитьВиртуальныеКаталоги(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля));
	
	// Разрешенные COM-классы
	Результат.Вставить("COMКлассы",
		ПолучитьРазрешенныеCOMКлассы(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля));
	
	// Внешние компоненты
	Результат.Вставить("ВнешниеКомпоненты",
		ПолучитьРазрешенныеВнешниеКомпоненты(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля));
	
	// Внешние модули
	Результат.Вставить("ВнешниеМодули",
		ПолучитьРазрешенныеВнешниеМодули(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля));
	
	// Приложения ОС
	Результат.Вставить("ПриложенияОС",
		ПолучитьРазрешенныеПриложенияОС(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля));
	
	// Интернет-ресурсы
	Результат.Вставить("ИнтернетРесурсы",
		ПолучитьРазрешенныеИнтернетРесурсы(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля));
	
	Возврат Результат;
	
КонецФункции

// Создает профиль безопасности по переданному описанию.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  СвойстваПрофиляБезопасности - см. АдминистрированиеКластераКлиентСервер.СвойстваПрофиляБезопасности
//
Процедура СоздатьПрофильБезопасности(Знач ПараметрыАдминистрированияКластера, Знач СвойстваПрофиляБезопасности) Экспорт
	
	ИмяПрофиля = СвойстваПрофиляБезопасности.Имя;
	
	Фильтр = Новый Структура("Имя", ИмяПрофиля);
	
	ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
	
	ПрофилиБезопасности = ПолучитьПрофилиБезопасности(ИдентификаторКластера, ПараметрыАдминистрированияКластера, Фильтр);
	
	Если ПрофилиБезопасности.Количество() = 1 Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'В кластере серверов %1 уже зарегистрирован профиль безопасности %2.'"), ИдентификаторКластера, ИмяПрофиля);
	КонецЕсли;
	
	ОбновитьСвойстваПрофиляБезопасности(ПараметрыАдминистрированияКластера, СвойстваПрофиляБезопасности, Ложь);
	
КонецПроцедуры

// Устанавливает свойства для существующего профиля безопасности по переданному описанию.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  СвойстваПрофиляБезопасности - см. АдминистрированиеКластераКлиентСервер.СвойстваПрофиляБезопасности
//
Процедура УстановитьСвойстваПрофиляБезопасности(Знач ПараметрыАдминистрированияКластера, Знач СвойстваПрофиляБезопасности)  Экспорт
	
	ИмяПрофиля = СвойстваПрофиляБезопасности.Имя;
	
	Фильтр = Новый Структура("Имя", ИмяПрофиля);
	
	ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
	
	ПрофилиБезопасности = ПолучитьПрофилиБезопасности(ИдентификаторКластера, ПараметрыАдминистрированияКластера, Фильтр);
	
	Если ПрофилиБезопасности.Количество() <> 1 Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'В кластере серверов %1 не зарегистрирован профиль безопасности %2.'"), ИдентификаторКластера, ИмяПрофиля);
	КонецЕсли;
	
	ОбновитьСвойстваПрофиляБезопасности(ПараметрыАдминистрированияКластера, СвойстваПрофиляБезопасности, Истина);
	
КонецПроцедуры

// Удаляет профиль безопасности.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ИмяПрофиля - Строка - имя профиля безопасности.
//
Процедура УдалитьПрофильБезопасности(Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля) Экспорт
	
	Шаблон = "%rac profile --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% remove --name=%name%";
	
	ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
	
	Параметры = Новый Соответствие();
	
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	Параметры.Вставить("name", ИмяПрофиля);
	
	ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
	
КонецПроцедуры

#КонецОбласти

#Область ИнформационныеБазы

// Возвращает внутренний идентификатор информационной базы.
//
// Параметры:
//  ИдентификаторКластера - Строка -внутренний идентификатор кластера серверов.
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ПараметрыАдминистрированияИнформационнойБазы - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//
// Возвращаемое значение:
//   Строка - внутренний идентификатор информационной базы.
//
Функция ИдентификаторИнформационнойБазы(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИнформационнойБазы) Экспорт
	
	Фильтр = Новый Структура("name", ПараметрыАдминистрированияИнформационнойБазы.ИмяВКластере);
	
	ИнформационныеБазы = СвойстваИнформационныхБаз(ИдентификаторКластера, ПараметрыАдминистрированияКластера, Фильтр);
	
	Если ИнформационныеБазы.Количество() = 1 Тогда
		Возврат ИнформационныеБазы[0].Получить("infobase");
	Иначе
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'В кластере серверов %1 не зарегистрирована информационная база %2.'"), ИдентификаторКластера, ПараметрыАдминистрированияИнформационнойБазы.ИмяВКластере);
	КонецЕсли;
	
КонецФункции

// Возвращает описания информационных баз.
//
// Параметры:
//  ИдентификаторКластера - Строка - внутренний идентификатор кластера серверов,
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  Фильтр - Структура - параметры фильтрации информационных баз.
//
// Возвращаемое значение:
//   Массив из Структура
//
Функция СвойстваИнформационныхБаз(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач Фильтр = Неопределено) Экспорт
	
	Шаблон = "%rac infobase summary --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% list";
	
	Параметры = Новый Соответствие();
	
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	
	ПотокВывода = ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
	Результат = ПарсерВывода(ПотокВывода, Неопределено, Фильтр);
	Возврат Результат;
	
КонецФункции

#КонецОбласти

#Область Кластер

// Возвращает внутренний идентификатор кластера серверов.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//
// Возвращаемое значение:
//  Строка - внутренний идентификатор кластера серверов.
//
Функция ИдентификаторКластера(Знач ПараметрыАдминистрированияКластера) Экспорт
	
	Фильтр = Новый Структура("port", ПараметрыАдминистрированияКластера.ПортКластера);
	
	Кластеры = СвойстваКластеров(ПараметрыАдминистрированияКластера, Фильтр);
	
	Если Кластеры.Количество() = 1 Тогда
		Возврат Кластеры[0].Получить("cluster");
	Иначе
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Не обнаружен кластер серверов с портом %1.'"), ПараметрыАдминистрированияКластера.ПортКластера);
	КонецЕсли;
	
КонецФункции

// Возвращает описания кластеров серверов.
//
// Параметры:
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  Фильтр - Структура - параметры фильтрации кластеров серверов.
//
// Возвращаемое значение:
//   Массив из Структура
//
Функция СвойстваКластеров(Знач ПараметрыАдминистрированияКластера, Знач Фильтр = Неопределено) Экспорт
	
	Шаблон = "%rac cluster list";
	ПотокВывода = ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера);
	Результат = ПарсерВывода(ПотокВывода, Неопределено, Фильтр);
	Возврат Результат;
	
КонецФункции

#КонецОбласти

#Область РабочиеПроцессыСерверы

// Возвращает описания рабочих процессов.
//
// Параметры:
//  ИдентификаторКластера - Строка - внутренний идентификатор кластера серверов.
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  Фильтр - Структура - параметры фильтрации рабочих процессов.
//
// Возвращаемое значение:
//   Массив из Структура
//
Функция СвойстваРабочихПроцессов(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач Фильтр = Неопределено) Экспорт
	
	Шаблон = "%rac process --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% list --server=%server%";
	
	Параметры = Новый Соответствие();
	
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	
	Результат = Новый Массив();
	РабочиеСерверы = СвойстваРабочихСерверов(ИдентификаторКластера, ПараметрыАдминистрированияКластера);
	Для Каждого РабочийСервер Из РабочиеСерверы Цикл
		Параметры.Вставить("server", РабочийСервер.Получить("server"));
		ПотокВывода = ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
		РабочиеПроцессыСервера = ПарсерВывода(ПотокВывода, Неопределено, Фильтр);
		Для Каждого РабочийПроцесс Из РабочиеПроцессыСервера Цикл
			Результат.Добавить(РабочийПроцесс);
		КонецЦикла;
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

// Возвращает описания рабочих серверов.
//
// Параметры:
//  ИдентификаторКластера - Строка - внутренний идентификатор кластера серверов,
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  Фильтр - Структура - параметры фильтрации рабочих серверов.
//
// Возвращаемое значение:
//   Массив из Структура.
//
Функция СвойстваРабочихСерверов(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач Фильтр = Неопределено) Экспорт
	
	Шаблон = "%rac server --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% list";
	
	Параметры = Новый Соответствие();
	
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	
	ПотокВывода = ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
	Результат = ПарсерВывода(ПотокВывода, Неопределено, Фильтр);
	Возврат Результат;
	
КонецФункции

#КонецОбласти

// Возвращает описания сеансов информационной базы.
//
// Параметры:
//  ИдентификаторКластера - Строка - внутренний идентификатор кластера серверов,
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ИдентификаторИнформационнойБазы - Строка - внутренний идентификатор информационной базы,
//  ПараметрыАдминистрированияИнформационнойБазы - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//  Фильтр - см. АдминистрированиеКластера.ФильтрСеансов, Массив из см. АдминистрированиеКластера.ФильтрСеансов
//  ИспользоватьСловарь - Булево - если Истина - возвращаемый результат будет заполнен с использованием словаря.
//
// Возвращаемое значение:
//   - Массив из см. АдминистрированиеКластераКлиентСервер.СвойстваСеанса
//   - Массив из Соответствие
//
Функция СвойстваСеансов(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ИдентификаторИнформационнойБазы, Знач Фильтр = Неопределено, Знач ИспользоватьСловарь = Истина) Экспорт
	
	Шаблон = "%rac session --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% list --infobase=%infobase%";	
	
	Параметры = Новый Соответствие();
	
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	
	Параметры.Вставить("infobase", ИдентификаторИнформационнойБазы);
	
	Если ИспользоватьСловарь Тогда
		Словарь = СловарьСвойствСеансов();
	Иначе
		Словарь = Неопределено;
		Фильтр = ФильтрВНотациюRac(Фильтр, СловарьСвойствСеансов());
	КонецЕсли;
	
	ПотокВывода = ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
	Результат = ПарсерВывода(ПотокВывода, Словарь, Фильтр);
	Возврат Результат;
	
КонецФункции

// Возвращает описания соединений с информационной базой.
//
// Параметры:
//  ИдентификаторКластера - Строка - внутренний идентификатор кластера серверов.
//  ПараметрыАдминистрированияКластера - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияКластера
//  ИдентификаторИнформационнойБазы - Строка - внутренний идентификатор информационной базы.
//  ПараметрыАдминистрированияИнформационнойБазы - см. АдминистрированиеКластераКлиентСервер.ПараметрыАдминистрированияИнформационнойБазыКластера
//  Фильтр - см. АдминистрированиеКластера.ФильтрСоединений, Массив из см. АдминистрированиеКластера.ФильтрСоединений
//  ИспользоватьСловарь - Булево - если Истина, то возвращаемый результат будет заполнен с использованием словаря.
//
// Возвращаемое значение:
//   - Массив из см. АдминистрированиеКластераКлиентСервер.СвойстваСоединения
//   - Массив из Соответствие
//
Функция СвойстваСоединений(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ИдентификаторИнформационнойБазы, Знач ПараметрыАдминистрированияИнформационнойБазы, Знач Фильтр = Неопределено, Знач ИспользоватьСловарь = Ложь) Экспорт
	
	Шаблон = "%rac connection --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% list --process=%process% --infobase=%infobase% --infobase-user=%?infobase-user% --infobase-pwd=%?infobase-pwd%";
	
	Параметры = Новый Соответствие();
	
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	
	Параметры.Вставить("infobase", ИдентификаторИнформационнойБазы);
	ЗаполнитьПараметрыАутентификацииВИБ(ПараметрыАдминистрированияИнформационнойБазы, Параметры);
	
	Если ИспользоватьСловарь Тогда
		Словарь = СловарьСвойствСоединений();
	Иначе
		Словарь = Неопределено;
		Фильтр = ФильтрВНотациюRac(Фильтр, СловарьСвойствСоединений());
	КонецЕсли;
	
	Результат = Новый Массив();
	РабочиеПроцессы = СвойстваРабочихПроцессов(ИдентификаторКластера, ПараметрыАдминистрированияКластера);
	
	Для Каждого РабочийПроцесс Из РабочиеПроцессы Цикл
		
		Параметры.Вставить("process", РабочийПроцесс.Получить("process"));
		ПотокВывода = ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
		СоединенияРабочегоПроцесса = ПарсерВывода(ПотокВывода, Словарь, Фильтр);
		Для Каждого Соединение Из СоединенияРабочегоПроцесса Цикл
			Если Не ИспользоватьСловарь Тогда
				Соединение.Вставить("process", РабочийПроцесс.Получить("process"));
			КонецЕсли;
			Результат.Добавить(Соединение);
		КонецЦикла;
		
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

// Возвращает путь к консольному клиенту сервера администрирования.
//
// Возвращаемое значение:
//  Строка
//
Функция ПутьККлиентуСервераАдминистрирования() Экспорт
	
	КаталогЗапуска = КаталогИсполняемыхФайловПлатформы();
	Клиент = КаталогЗапуска + "rac";
	
	СисИнфо = Новый СистемнаяИнформация();
	Если (СисИнфо.ТипПлатформы = ТипПлатформы.Windows_x86) Или (СисИнфо.ТипПлатформы = ТипПлатформы.Windows_x86_64) Тогда
		Клиент = Клиент + ".exe";
	КонецЕсли;
	
	Возврат Клиент;
	
КонецФункции

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

Функция КаталогИсполняемыхФайловПлатформы()
	
	Результат = КаталогПрограммы();
	СимволРазделителя = ПолучитьРазделительПути();
	
	Если Не СтрЗаканчиваетсяНа(Результат, СимволРазделителя) Тогда
		Результат = Результат + СимволРазделителя;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция СвойстваИнформационнойБазы(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ, Знач Словарь)
	
	Шаблон = "%rac infobase --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% info --infobase=%infobase% --infobase-user=%?infobase-user% --infobase-pwd=%?infobase-pwd%";
	
	Параметры = Новый Соответствие();
	
	ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	
	ИдентификаторИнформационнойБазы = ИдентификаторИнформационнойБазы(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ПараметрыАдминистрированияИБ);
	Параметры.Вставить("infobase", ИдентификаторИнформационнойБазы);
	ЗаполнитьПараметрыАутентификацииВИБ(ПараметрыАдминистрированияИБ, Параметры);
	
	ПотокВывода = ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
	Результат = ПарсерВывода(ПотокВывода, Словарь);
	Возврат Результат[0];
	
КонецФункции

Процедура УстановитьСвойстваИнформационнойБазы(Знач ПараметрыАдминистрированияКластера, Знач ПараметрыАдминистрированияИБ, Знач Словарь, Знач ЗначенияСвойств)
	
	Шаблон = "%rac infobase --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% update --infobase=%infobase% --infobase-user=%?infobase-user% --infobase-pwd=%?infobase-pwd%";
	
	Параметры = Новый Соответствие();
	
	ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	
	ИдентификаторИнформационнойБазы = ИдентификаторИнформационнойБазы(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ПараметрыАдминистрированияИБ);
	Параметры.Вставить("infobase", ИдентификаторИнформационнойБазы);
	ЗаполнитьПараметрыАутентификацииВИБ(ПараметрыАдминистрированияИБ, Параметры);
	
	ЗаполнитьПараметрыПоСловарю(Словарь, ЗначенияСвойств, Параметры, Шаблон);
	
	ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
	
КонецПроцедуры

Функция ПолучитьПрофилиБезопасности(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач Фильтр = Неопределено)
	
	Шаблон = "%rac profile --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% list";
	
	Параметры = Новый Соответствие();
	
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	
	ПотокВывода = ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
	Результат = ПарсерВывода(ПотокВывода, СловарьСвойствПрофиляБезопасности(), Фильтр);
	Возврат Результат;
	
КонецФункции

Функция ПолучитьВиртуальныеКаталоги(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля, Знач Фильтр = Неопределено)
	
	Возврат СпискиКонтроляДоступа(
		ИдентификаторКластера,
		ПараметрыАдминистрированияКластера,
		ИмяПрофиля,
		"directory", // Не локализуется
		СловарьСвойствВиртуальногоКаталога());
	
КонецФункции

Функция ПолучитьРазрешенныеCOMКлассы(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля, Знач Фильтр = Неопределено)
	
	Возврат СпискиКонтроляДоступа(
		ИдентификаторКластера,
		ПараметрыАдминистрированияКластера,
		ИмяПрофиля,
		"com", // Не локализуется
		СловарьСвойствCOMКласса());
	
КонецФункции

Функция ПолучитьРазрешенныеВнешниеКомпоненты(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля, Знач Фильтр = Неопределено)
	
	Возврат СпискиКонтроляДоступа(
		ИдентификаторКластера,
		ПараметрыАдминистрированияКластера,
		ИмяПрофиля,
		"addin", // Не локализуется
		СловарьСвойствВнешнейКомпоненты());
	
КонецФункции

Функция ПолучитьРазрешенныеВнешниеМодули(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля, Знач Фильтр = Неопределено)
	
	Возврат СпискиКонтроляДоступа(
		ИдентификаторКластера,
		ПараметрыАдминистрированияКластера,
		ИмяПрофиля,
		"module", // Не локализуется
		СловарьСвойствВнешнегоМодуля());
	
КонецФункции

Функция ПолучитьРазрешенныеПриложенияОС(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля, Знач Фильтр = Неопределено)
	
	Возврат СпискиКонтроляДоступа(
		ИдентификаторКластера,
		ПараметрыАдминистрированияКластера,
		ИмяПрофиля,
		"app", // Не локализуется
		СловарьСвойствПриложенияОС());
	
КонецФункции

Функция ПолучитьРазрешенныеИнтернетРесурсы(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля, Знач Фильтр = Неопределено)
	
	Возврат СпискиКонтроляДоступа(
		ИдентификаторКластера,
		ПараметрыАдминистрированияКластера,
		ИмяПрофиля,
		"inet", // Не локализуется
		СловарьСвойствИнтернетРесурса());
	
КонецФункции

// Параметры:
//  ИдентификаторКластера - Строка
//  ПараметрыАдминистрированияКластера - Структура:
//   * ТипПодключения - Строка
//   * АдресАгентаСервера - Строка
//   * ПортАгентаСервера - Число
//   * АдресСервераАдминистрирования - Строка
//   * ПортСервераАдминистрирования - Число
//   * ПортКластера - Число
//   * ИмяАдминистратораКластера - Строка
//   * ПарольАдминистратораКластера - Строка
//  ИмяПрофиля - Строка
//  ИмяСписка - Строка
//  Словарь - ФиксированнаяСтруктура:
//   * Имя - Строка
//   * Описание - Строка
//   * ХэшСумма - Строка - для обратной совместимости.
//  Фильтр - Неопределено
// Возвращаемое значение:
//  Массив из см. СловарьСвойствВнешнейКомпоненты
//
Функция СпискиКонтроляДоступа(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля, Знач ИмяСписка, Знач Словарь, Знач Фильтр = Неопределено)
	
	Шаблон = "%rac profile --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% acl --name=%name% directory list";
	Шаблон = СтрЗаменить(Шаблон, "directory", ИмяСписка);
	
	Параметры = Новый Соответствие();
	
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	
	Параметры.Вставить("name", ИмяПрофиля);
	
	ПотокВывода = ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
	Результат = ПарсерВывода(ПотокВывода, Словарь, Фильтр);
	Возврат Результат;
	
КонецФункции

Процедура ОбновитьСвойстваПрофиляБезопасности(Знач ПараметрыАдминистрированияКластера, Знач СвойстваПрофиляБезопасности, Знач ОчиститьСпискиКонтроляДоступа)
	
	ИмяПрофиля = СвойстваПрофиляБезопасности.Имя;
	
	Шаблон = "%rac profile --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% update ";
	
	Параметры = Новый Соответствие();
	
	ИдентификаторКластера = ИдентификаторКластера(ПараметрыАдминистрированияКластера);
	Параметры.Вставить("cluster", ИдентификаторКластера);
	
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	ЗаполнитьПараметрыПоСловарю(СловарьСвойствПрофиляБезопасности(Ложь), СвойстваПрофиляБезопасности, Параметры, Шаблон);
	
	ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
	
	СловарьСвойствИспользованияСписковКонтроляДоступа = СловарьСвойствИспользованияСписокКонтроляДоступа();
	Для Каждого ФрагментСловаря Из СловарьСвойствИспользованияСписковКонтроляДоступа Цикл
		УстановитьИспользованиеСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ФрагментСловаря.Значение, Не СвойстваПрофиляБезопасности[ФрагментСловаря.Ключ]);
	КонецЦикла;
	
	// Виртуальный каталоги
	ИмяСписка = "directory";
	ТекущийСловарь = СловарьСвойствВиртуальногоКаталога();
	Если ОчиститьСпискиКонтроляДоступа Тогда
		УдаляемыеВиртуальныеКаталоги = СпискиКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, ТекущийСловарь);
		Для Каждого УдаляемыйВиртуальныйКаталог Из УдаляемыеВиртуальныеКаталоги Цикл
			УдалитьЭлементСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, УдаляемыйВиртуальныйКаталог.ЛогическийURL);
		КонецЦикла;
	КонецЕсли;
	СоздаваемыеВиртуальныеКаталоги = СвойстваПрофиляБезопасности.ВиртуальныеКаталоги;
	Для Каждого СоздаваемыйВиртуальныйКаталог Из СоздаваемыеВиртуальныеКаталоги Цикл
		СоздатьЭлементСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, ТекущийСловарь, СоздаваемыйВиртуальныйКаталог);
	КонецЦикла;
	
	// Разрешенные COM-классы
	ИмяСписка = "com";
	ТекущийСловарь = СловарьСвойствCOMКласса();
	Если ОчиститьСпискиКонтроляДоступа Тогда
		УдаляемыеCOMКлассы = СпискиКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, ТекущийСловарь);
		Для Каждого УдаляемыйCOMКласс Из УдаляемыеCOMКлассы Цикл
			УдалитьЭлементСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, УдаляемыйCOMКласс.Имя);
		КонецЦикла;
	КонецЕсли;
	СоздаваемыеCOMКлассы = СвойстваПрофиляБезопасности.COMКлассы;
	Для Каждого СоздаваемыйCOMКласс Из СоздаваемыеCOMКлассы Цикл
		СоздатьЭлементСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, ТекущийСловарь, СоздаваемыйCOMКласс);
	КонецЦикла;
	
	// Внешние компоненты
	ИмяСписка = "addin";
	ТекущийСловарь = СловарьСвойствВнешнейКомпоненты();
	Если ОчиститьСпискиКонтроляДоступа Тогда
		УдаляемыеВнешниеКомпоненты = СпискиКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, ТекущийСловарь);
		Для Каждого УдаляемыйВнешнийКомпонент Из УдаляемыеВнешниеКомпоненты Цикл
			УдалитьЭлементСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, УдаляемыйВнешнийКомпонент.Имя);
		КонецЦикла;
	КонецЕсли;
	СоздаваемыеВнешниеКомпоненты = СвойстваПрофиляБезопасности.ВнешниеКомпоненты;
	Для Каждого СоздаваемыйВнешнийКомпонент Из СоздаваемыеВнешниеКомпоненты Цикл
		СоздатьЭлементСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, ТекущийСловарь, СоздаваемыйВнешнийКомпонент);
	КонецЦикла;
	
	// Внешние модули
	ИмяСписка = "module";
	ТекущийСловарь = СловарьСвойствВнешнегоМодуля();
	Если ОчиститьСпискиКонтроляДоступа Тогда
		УдаляемыеВнешниеМодули = СпискиКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, ТекущийСловарь);
		Для Каждого УдаляемыйВнешнийМодуль Из УдаляемыеВнешниеМодули Цикл
			УдалитьЭлементСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, УдаляемыйВнешнийМодуль.Имя);
		КонецЦикла;
	КонецЕсли;
	СоздаваемыеВнешниеМодули = СвойстваПрофиляБезопасности.ВнешниеМодули;
	Для Каждого СоздаваемыйВнешнийМодуль Из СоздаваемыеВнешниеМодули Цикл
		СоздатьЭлементСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, ТекущийСловарь, СоздаваемыйВнешнийМодуль);
	КонецЦикла;
	
	// Приложения ОС
	ИмяСписка = "app";
	ТекущийСловарь = СловарьСвойствПриложенияОС();
	Если ОчиститьСпискиКонтроляДоступа Тогда
		УдаляемыеПриложенияОС = СпискиКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, ТекущийСловарь);
		Для Каждого УдаляемоеПриложениеОС Из УдаляемыеПриложенияОС Цикл
			УдалитьЭлементСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, УдаляемоеПриложениеОС.Имя);
		КонецЦикла;
	КонецЕсли;
	СоздаваемыеПриложенияОС = СвойстваПрофиляБезопасности.ПриложенияОС;
	Для Каждого СоздаваемоеПриложениеОС Из СоздаваемыеПриложенияОС Цикл
		СоздатьЭлементСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, ТекущийСловарь, СоздаваемоеПриложениеОС);
	КонецЦикла;
	
	// Интернет-ресурсы
	ИмяСписка = "inet";
	ТекущийСловарь = СловарьСвойствИнтернетРесурса();
	Если ОчиститьСпискиКонтроляДоступа Тогда
		УдаляемыеИнтернетРесурсы = СпискиКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, ТекущийСловарь);
		Для Каждого УдаляемыйИнтернетРесурс Из УдаляемыеИнтернетРесурсы Цикл
			УдалитьЭлементСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, УдаляемыйИнтернетРесурс.Имя);
		КонецЦикла;
	КонецЕсли;
	СоздаваемыеИнтернетРесурсы = СвойстваПрофиляБезопасности.ИнтернетРесурсы;
	Для Каждого СоздаваемыйИнтернетРесурс Из СоздаваемыеИнтернетРесурсы Цикл
		СоздатьЭлементСпискаКонтроляДоступа(ИдентификаторКластера, ПараметрыАдминистрированияКластера, ИмяПрофиля, ИмяСписка, ТекущийСловарь, СоздаваемыйИнтернетРесурс);
	КонецЦикла;
	
КонецПроцедуры

Процедура УстановитьИспользованиеСпискаКонтроляДоступа(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля, Знач ИмяСписка, Знач Использование)
	
	Шаблон = "%rac profile --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% acl --name=%name% directory --access=%access%";
	Шаблон = СтрЗаменить(Шаблон, "directory", ИмяСписка);
	
	Параметры = Новый Соответствие();
	
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	Параметры.Вставить("name", ИмяПрофиля);
	Если Использование Тогда
		Параметры.Вставить("access", "list");
	Иначе
		Параметры.Вставить("access", "full");
	КонецЕсли;
	
	ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
	
КонецПроцедуры

Процедура УдалитьЭлементСпискаКонтроляДоступа(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля, Знач ИмяСписка, Знач КлючЭлемента)
	
	КлючСписка = КлючиСписковКонтроляДоступа()[ИмяСписка];
	
	Шаблон = "%rac profile --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% acl --name=%name% directory remove --key=%key%";
	Шаблон = СтрЗаменить(Шаблон, "directory", ИмяСписка);
	Шаблон = СтрЗаменить(Шаблон, "key", КлючСписка);
	
	Параметры = Новый Соответствие();
	
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	Параметры.Вставить("name", ИмяПрофиля);
	Параметры.Вставить(КлючСписка, КлючЭлемента);
	
	ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
	
КонецПроцедуры

Процедура СоздатьЭлементСпискаКонтроляДоступа(Знач ИдентификаторКластера, Знач ПараметрыАдминистрированияКластера, Знач ИмяПрофиля, Знач ИмяСписка, Знач Словарь, Знач СвойстваЭлемента)
	
	Шаблон = "%rac profile --cluster=%cluster% --cluster-user=%?cluster-user% --cluster-pwd=%?cluster-pwd% acl --name=%profile_name% directory update";
	Шаблон = СтрЗаменить(Шаблон, "directory", ИмяСписка);
	
	Параметры = Новый Соответствие();
	
	Параметры.Вставить("cluster", ИдентификаторКластера);
	ЗаполнитьПараметрыАутентификацииВКластере(ПараметрыАдминистрированияКластера, Параметры);
	Параметры.Вставить("profile_name", ИмяПрофиля);
	
	ЗаполнитьПараметрыПоСловарю(Словарь, СвойстваЭлемента, Параметры, Шаблон);
	
	ВыполнитьКоманду(Шаблон, ПараметрыАдминистрированияКластера, Параметры);
	
КонецПроцедуры

Функция ПреобразоватьЗначенияСвойствИспользованияСписковДоступа(Знач СтруктураОписание)
	
	Словарь = СловарьСвойствИспользованияСписокКонтроляДоступа();
	
	Результат = Новый Структура;
	
	Для Каждого КлючИЗначение Из СтруктураОписание Цикл
		
		Если Словарь.Свойство(КлючИЗначение.Ключ) Тогда
			
			Если КлючИЗначение.Значение = "list" Тогда
				
				Значение = Ложь;
				
			ИначеЕсли КлючИЗначение.Значение = "full" Тогда
				
				Значение = Истина;
				
			КонецЕсли;
			
			Результат.Вставить(КлючИЗначение.Ключ, Значение);
			
		Иначе
			
			Результат.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

Функция ПривестиЗначение(Знач Значение, Знач ИмяПараметра = "")
	
	Если ТипЗнч(Значение) = Тип("Дата") Тогда
		Возврат Формат(Значение, "ДФ=гггг-ММ-ддTЧЧ:мм:сс");
	КонецЕсли;
	
	Если ТипЗнч(Значение) = Тип("Булево") Тогда
		
		Если ПустаяСтрока(ИмяПараметра) Тогда
			ФорматнаяСтрока = "БЛ=off; БИ=on";
		Иначе
			ФорматнаяСтрока = СловарьФорматированияБулевыхСвойств()[ИмяПараметра];
		КонецЕсли;
		
		Возврат Формат(Значение, ФорматнаяСтрока);
		
	КонецЕсли;
	
	Если ТипЗнч(Значение) = Тип("Число") Тогда
		Возврат Формат(Значение, "ЧРД=,; ЧН=0; ЧГ=0; ЧО=1");
	КонецЕсли;
	
	Если ТипЗнч(Значение) = Тип("Строка") Тогда
		Если СтрНайти(Значение, """") > 0 Или СтрНайти(Значение, " ") > 0 Или СтрНайти(Значение, "-") > 0 Или СтрНайти(Значение, "!") > 0 Тогда
			Возврат """" + СтрЗаменить(Значение, """", """""") + """";
		КонецЕсли;
	КонецЕсли;
	
	Возврат Строка(Значение);
	
КонецФункции

Функция ПривестиЭлементВывода(ЭлементВывода)
	
	Если ПустаяСтрока(ЭлементВывода) Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	ЭлементВывода = СтрЗаменить(ЭлементВывода, """""", """");
	
	Если ЭлементВывода = "on" Или ЭлементВывода = "yes" Тогда
		Возврат Истина;
	КонецЕсли;
	
	Если ЭлементВывода = "off" Или ЭлементВывода = "no" Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Если СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(ЭлементВывода) Тогда
		Возврат Число(ЭлементВывода);
	КонецЕсли;
	
	Попытка
		Возврат XMLЗначение(Тип("Дата"), ЭлементВывода);
	Исключение
		// Обработка исключения не требуется. Ожидаемое исключение - ошибка
		// преобразования к типу Дата.
		Возврат ЭлементВывода;
	КонецПопытки;
	
КонецФункции

Функция ВыполнитьКоманду(Знач Шаблон, Знач ПараметрыАдминистрированияКластера, Знач ЗначенияПараметров = Неопределено)
	
	// АПК:547-выкл код сохранен для обратной совместимости, используется в устаревшем программном интерфейсе.
	
	#Если Сервер Тогда
		
		Если БезопасныйРежим() <> Ложь Тогда
			ВызватьИсключение НСтр("ru = 'Внимание! Администрирование кластера невозможно в безопасном режиме.'");
		КонецЕсли;
		
		Если ОбщегоНазначения.РазделениеВключено() Тогда
			ВызватьИсключение НСтр("ru = 'Внимание! В модели сервиса недопустимо выполнение прикладной информационной базой функций администрирования кластера.'");
		КонецЕсли;
		
	#КонецЕсли
	
	// АПК:547-вкл
	
	// Подставим в командную строку путь до утилиты rac и адрес сервера ras.
	Клиент = ПутьККлиентуСервераАдминистрирования();
	ФайлКлиента = Новый Файл(Клиент);
	Если Не ФайлКлиента.Существует() Тогда
		
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Невозможно выполнить операцию администрирования кластера серверов по причине: не существует файл %1.
			      |
			      |Для администрирования кластера через сервер администрирования (ras) установите на данном
			      |компьютере клиент сервера администрирования (rac).
			      |Для его установки:
			      |- Для компьютеров с ОС Windows переустановите платформу, установив компонент ""Администрирование сервера 1С:Предприятия"";
			      |- Для компьютеров с ОС Linux установите пакет 1c-enterprise83-server*.'"),
			ФайлКлиента.ПолноеИмя);
		
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ПараметрыАдминистрированияКластера.АдресСервераАдминистрирования) Тогда
		Сервер = СокрЛП(ПараметрыАдминистрированияКластера.АдресСервераАдминистрирования);
		Если ЗначениеЗаполнено(ПараметрыАдминистрированияКластера.ПортСервераАдминистрирования) Тогда
			Сервер = Сервер + ":" + ПривестиЗначение(ПараметрыАдминистрированияКластера.ПортСервераАдминистрирования);
		Иначе
			Сервер = Сервер + ":1545";
		КонецЕсли;
	Иначе
		Сервер = "";
	КонецЕсли;
	
	КоманднаяСтрока = """" + Клиент + """ " + СтрЗаменить(Шаблон, "%rac", Сервер);
	
	// Подставим в командную строку значения параметров.
	Если ЗначениеЗаполнено(ЗначенияПараметров) Тогда
		Для Каждого Параметр Из ЗначенияПараметров Цикл
			// Заполним значение параметра.
			КоманднаяСтрока = СтрЗаменить(КоманднаяСтрока, "%" + Параметр.Ключ + "%", ПривестиЗначение(Параметр.Значение, Параметр.Ключ));
			Если ЗначениеЗаполнено(Параметр.Значение) Тогда
				// Это мог быть необязательный параметр.
				КоманднаяСтрока = СтрЗаменить(КоманднаяСтрока, "%?" + Параметр.Ключ + "%", ПривестиЗначение(Параметр.Значение, Параметр.Ключ));
			Иначе
				// Если необязательный параметр не установлен - вообще вырежем его из командной строки.
				КоманднаяСтрока = СтрЗаменить(КоманднаяСтрока, "--" + Параметр.Ключ + "=%?" + Параметр.Ключ + "%", "");
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	// АПК:223-выкл  код сохранен для обратной совместимости, используется в устаревшем программном интерфейсе.
	
	ПараметрыЗапускаПрограммы = ОбщегоНазначенияКлиентСервер.ПараметрыЗапускаПрограммы();
	ПараметрыЗапускаПрограммы.ТекущийКаталог = КаталогИсполняемыхФайловПлатформы();
	ПараметрыЗапускаПрограммы.ДождатьсяЗавершения = Истина;
	ПараметрыЗапускаПрограммы.ПолучитьПотокВывода = Истина;
	ПараметрыЗапускаПрограммы.ПолучитьПотокОшибок = Истина;
	
	Результат = ОбщегоНазначенияКлиентСервер.ЗапуститьПрограмму(КоманднаяСтрока, ПараметрыЗапускаПрограммы);
	
	// АПК:223-вкл
	
	ПотокВывода = Результат.ПотокВывода;
	ПотокОшибок = Результат.ПотокОшибок;
	
	Если ЗначениеЗаполнено(ПотокОшибок) Тогда
		ВызватьИсключение ПотокОшибок;
	КонецЕсли;
	
	Возврат ПотокВывода;
	
КонецФункции

Функция ПарсерВывода(Знач ПотокВывода, Знач Словарь, Знач Фильтр = Неопределено)
	
	Результат = Новый Массив();
	ЭлементРезультата = Новый Соответствие();
	
	РазмерВывода = СтрЧислоСтрок(ПотокВывода);
	Для Шаг = 1 По РазмерВывода Цикл
		ЭлементПотока = СтрПолучитьСтроку(ПотокВывода, Шаг);
		ЭлементПотока = СокрЛП(ЭлементПотока);
		ПоложениеРазделителя = СтрНайти(ЭлементПотока, ":");
		Если ПоложениеРазделителя > 0 Тогда
			
			ИмяСвойства = СокрЛП(Лев(ЭлементПотока, ПоложениеРазделителя - 1));
			ЗначениеСвойства = ПривестиЭлементВывода(СокрЛП(Прав(ЭлементПотока, СтрДлина(ЭлементПотока) - ПоложениеРазделителя)));
			
			Если СвойстваЭкранируемыеКавычками().Получить(ИмяСвойства) <> Неопределено Тогда
				Если СтрНачинаетсяС(ЗначениеСвойства, """") И СтрЗаканчиваетсяНа(ЗначениеСвойства, """") Тогда
					ЗначениеСвойства = Лев(ЗначениеСвойства, СтрДлина(ЗначениеСвойства) - 1);
					ЗначениеСвойства = Прав(ЗначениеСвойства, СтрДлина(ЗначениеСвойства) - 1)
				КонецЕсли;
			КонецЕсли;
			
			ЭлементРезультата.Вставить(ИмяСвойства, ЗначениеСвойства);
			
		Иначе
			
			Если ЭлементРезультата.Количество() > 0 Тогда
				ПарсерЭлементаВывода(ЭлементРезультата, Результат, Словарь, Фильтр);
				ЭлементРезультата = Новый Соответствие();
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Если ЭлементРезультата.Количество() > 0 Тогда
		ПарсерЭлементаВывода(ЭлементРезультата, Результат, Словарь, Фильтр);
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Процедура ПарсерЭлементаВывода(ЭлементРезультата, Результат, Словарь, Фильтр)
	
	Если Словарь <> Неопределено Тогда
		Объект = РазобратьЭлементВывода(ЭлементРезультата, Словарь);
	Иначе
		Объект = ЭлементРезультата;
	КонецЕсли;
	
	Если Фильтр <> Неопределено И Не АдминистрированиеКластераКлиентСервер.ПроверитьУсловияФильтра(Объект, Фильтр) Тогда
		Возврат;
	КонецЕсли;
	
	Результат.Добавить(Объект);
	
КонецПроцедуры

Функция РазобратьЭлементВывода(Знач ЭлементВывода, Знач Словарь)
	
	Результат = Новый Структура();
	
	Для Каждого ФрагментСловаря Из Словарь Цикл
		
		Результат.Вставить(ФрагментСловаря.Ключ, ЭлементВывода[ФрагментСловаря.Значение]);
		
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

Процедура ЗаполнитьПараметрыАутентификацииВКластере(Знач ПараметрыАдминистрированияКластера, Параметры)
	
	Параметры.Вставить("cluster-user", ПараметрыАдминистрированияКластера.ИмяАдминистратораКластера);
	Параметры.Вставить("cluster-pwd", ПараметрыАдминистрированияКластера.ПарольАдминистратораКластера);
	
КонецПроцедуры

Процедура ЗаполнитьПараметрыАутентификацииВИБ(Знач ПараметрыАдминистрированияИБ, Параметры)
	
	Параметры.Вставить("infobase-user", ПараметрыАдминистрированияИБ.ИмяАдминистратораИнформационнойБазы);
	Параметры.Вставить("infobase-pwd", ПараметрыАдминистрированияИБ.ПарольАдминистратораИнформационнойБазы);
	
КонецПроцедуры

Процедура ЗаполнитьПараметрыПоСловарю(Знач Словарь, Знач Источник, Параметры, Шаблон)
	
	Для Каждого ФрагментСловаря Из Словарь Цикл
		
		Шаблон = Шаблон + " --" + ФрагментСловаря.Значение + "=%" + ФрагментСловаря.Значение + "%";
		Параметры.Вставить(ФрагментСловаря.Значение, Источник[ФрагментСловаря.Ключ]);
		
	КонецЦикла;
	
КонецПроцедуры

Функция ФильтрВНотациюRac(Знач Фильтр, Знач Словарь)
	
	Если Фильтр = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Если Словарь = Неопределено Тогда
		Возврат Фильтр;
	КонецЕсли;
	
	Результат = Новый Массив();
	
	Для Каждого Условие Из Фильтр Цикл
		
		Если ТипЗнч(Условие) = Тип("КлючИЗначение") Тогда
			
			Результат.Добавить(Новый Структура("Свойство, ВидСравнения, Значение", Словарь[Условие.Ключ], ВидСравнения.Равно, Условие.Значение));
			
		ИначеЕсли ТипЗнч(Условие) = Тип("Структура") Тогда
			
			Результат.Добавить(Новый Структура("Свойство, ВидСравнения, Значение", Словарь[Условие.Свойство], Условие.ВидСравнения, Условие.Значение));
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

Функция СловарьСвойствБлокировкиСеансовИРегламентныхЗаданий()
	
	Результат = Новый Структура();
	
	Результат.Вставить("БлокировкаСеансов", "sessions-deny");
	Результат.Вставить("ДатаС", "denied-from");
	Результат.Вставить("ДатаПо", "denied-to");
	Результат.Вставить("Сообщение", "denied-message");
	Результат.Вставить("КодРазрешения", "permission-code");
	Результат.Вставить("ПараметрБлокировки", "denied-parameter");
	Результат.Вставить("БлокировкаРегламентныхЗаданий", "scheduled-jobs-deny");
	
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

Функция СловарьСвойствСеансов()
	
	Результат = Новый Структура();
	
	Результат.Вставить("Номер", "session-id");
	Результат.Вставить("ИмяПользователя", "user-name");
	Результат.Вставить("ИмяКлиентскогоКомпьютера", "host");
	Результат.Вставить("ИдентификаторКлиентскогоПриложения", "app-id");
	Результат.Вставить("ИдентификаторЯзыка", "locale");
	Результат.Вставить("МоментСозданияСеанса", "started-at");
	Результат.Вставить("МоментПоследнейАктивностиСеанса", "last-active-at");
	Результат.Вставить("БлокировкаСУБД", "blocked-by-dbms");
	Результат.Вставить("Блокировка", "blocked-by-ls");
	Результат.Вставить("Передано", "bytes-all");
	Результат.Вставить("ПереданоЗа5Минут", "bytes-last-5min");
	Результат.Вставить("СерверныхВызовов", "calls-all");
	Результат.Вставить("СерверныхВызововЗа5Минут", "calls-last-5min");
	Результат.Вставить("ДлительностьСерверныхВызовов", "duration-all");
	Результат.Вставить("ДлительностьТекущегоСерверногоВызова", "duration-current");
	Результат.Вставить("ДлительностьСерверныхВызововЗа5Минут", "duration-last-5min");
	Результат.Вставить("ПереданоСУБД", "dbms-bytes-all");
	Результат.Вставить("ПереданоСУБДЗа5Минут", "dbms-bytes-last-5min");
	Результат.Вставить("ДлительностьВызововСУБД", "duration-all-dbms");
	Результат.Вставить("ДлительностьТекущегоВызоваСУБД", "duration-current-dbms");
	Результат.Вставить("ДлительностьВызововСУБДЗа5Минут", "duration-last-3min-dbms");
	Результат.Вставить("СоединениеСУБД", "db-proc-info");
	Результат.Вставить("ВремяСоединенияСУБД", "db-proc-took");
	Результат.Вставить("МоментЗахватаСоединенияСУБД", "db-proc-took-at");
	
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

Функция СловарьСвойствСоединений()
	
	Результат = Новый Структура();
	
	Результат.Вставить("Номер", "conn-id");
	Результат.Вставить("ИмяПользователя", "user-name");
	Результат.Вставить("ИмяКлиентскогоКомпьютера", "host");
	Результат.Вставить("ИдентификаторКлиентскогоПриложения", "app-id");
	Результат.Вставить("МоментУстановкиСоединения", "connected-at");
	Результат.Вставить("РежимСоединенияСИнформационнойБазой", "ib-conn-mode");
	Результат.Вставить("РежимСоединенияСБазойДанных", "db-conn-mode");
	Результат.Вставить("БлокировкаСУБД", "blocked-by-dbms");
	Результат.Вставить("Передано", "bytes-all");
	Результат.Вставить("ПереданоЗа5Минут", "bytes-last-5min");
	Результат.Вставить("СерверныхВызовов", "calls-all");
	Результат.Вставить("СерверныхВызововЗа5Минут", "calls-last-5min");
	Результат.Вставить("ПереданоСУБД", "dbms-bytes-all");
	Результат.Вставить("ПереданоСУБДЗа5Минут", "dbms-bytes-last-5min");
	Результат.Вставить("СоединениеСУБД", "db-proc-info");
	Результат.Вставить("ВремяСУБД", "db-proc-took");
	Результат.Вставить("МоментЗахватаСоединенияСУБД", "db-proc-took-at");
	Результат.Вставить("ДлительностьСерверныхВызовов", "duration-all");
	Результат.Вставить("ДлительностьВызововСУБД", "duration-all-dbms");
	Результат.Вставить("ДлительностьТекущегоСерверногоВызова", "duration-current");
	Результат.Вставить("ДлительностьТекущегоВызоваСУБД", "duration-current-dbms");
	Результат.Вставить("ДлительностьСерверныхВызововЗа5Минут", "duration-last-5min");
	Результат.Вставить("ДлительностьВызововСУБДЗа5Минут", "duration-last-5min-dbms");
	
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

Функция СловарьСвойствПрофиляБезопасности(Знач ВключаяСвойстваИспользованияСписковКонтроляДоступа = Истина)
	
	Результат = Новый Структура();
	
	Результат.Вставить("Имя", "name");
	Результат.Вставить("Описание", "descr");
	Результат.Вставить("ПрофильБезопасногоРежима", "config");
	Результат.Вставить("ПолныйДоступКПривилегированномуРежиму", "priv");
	
	Если ВключаяСвойстваИспользованияСписковКонтроляДоступа Тогда
		
		СловарьСвойствИспользованияСписковКонтроляДоступа = СловарьСвойствИспользованияСписокКонтроляДоступа();
		
		Для Каждого ФрагментСловаря Из СловарьСвойствИспользованияСписковКонтроляДоступа Цикл
			Результат.Вставить(ФрагментСловаря.Ключ, ФрагментСловаря.Значение);
		КонецЦикла;
		
	КонецЕсли;
	
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

Функция СловарьСвойствИспользованияСписокКонтроляДоступа()
	
	Результат = Новый Структура();
	
	Результат.Вставить("ПолныйДоступКФайловойСистеме", "directory");
	Результат.Вставить("ПолныйДоступКCOMОбъектам", "com");
	Результат.Вставить("ПолныйДоступКВнешнимКомпонентам", "addin");
	Результат.Вставить("ПолныйДоступКВнешнимМодулям", "module");
	Результат.Вставить("ПолныйДоступКПриложениямОперационнойСистемы", "app");
	Результат.Вставить("ПолныйДоступКИнтернетРесурсам", "inet");
	
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

Функция СловарьСвойствВиртуальногоКаталога()
	
	Результат = Новый Структура();
	
	Результат.Вставить("ЛогическийURL", "alias");
	Результат.Вставить("ФизическийURL", "physicalPath");
	
	Результат.Вставить("Описание", "descr");
	
	Результат.Вставить("ЧтениеДанных", "allowedRead");
	Результат.Вставить("ЗаписьДанных", "allowedWrite");
	
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

Функция СловарьСвойствCOMКласса()
	
	Результат = Новый Структура();
	
	Результат.Вставить("Имя", "name");
	Результат.Вставить("Описание", "descr");
	
	Результат.Вставить("ФайлМоникер", "fileName");
	Результат.Вставить("CLSID", "id");
	Результат.Вставить("Компьютер", "host");
	
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

// Возвращаемое значение:
//  ФиксированнаяСтруктура:
//   * Имя - Строка
//   * Описание - Строка
//   * ХэшСумма - Строка - для обратной совместимости.
//
Функция СловарьСвойствВнешнейКомпоненты()
	
	Результат = Новый Структура();
	Результат.Вставить("Имя", "name");
	Результат.Вставить("Описание", "descr");
	Результат.Вставить("ХэшСумма", "hash"); // АПК:1036 для обратной совместимости
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

Функция СловарьСвойствВнешнегоМодуля()
	
	Результат = Новый Структура();
	Результат.Вставить("Имя", "name");
	Результат.Вставить("Описание", "descr");
	Результат.Вставить("ХэшСумма", "hash"); // АПК:1036 для обратной совместимости	
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

Функция СловарьСвойствПриложенияОС()
	
	Результат = Новый Структура();
	
	Результат.Вставить("Имя", "name");
	Результат.Вставить("Описание", "descr");
	
	Результат.Вставить("ШаблонСтрокиЗапуска", "wild");
	
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

Функция СловарьСвойствИнтернетРесурса()
	
	Результат = Новый Структура();
	
	Результат.Вставить("Имя", "name");
	Результат.Вставить("Описание", "descr");
	
	Результат.Вставить("Протокол", "protocol");
	Результат.Вставить("Адрес", "url");
	Результат.Вставить("Порт", "port");
	
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

Функция КлючиСписковКонтроляДоступа()
	
	Результат = Новый Структура();
	
	Результат.Вставить("directory", "alias");
	Результат.Вставить("com", "name");
	Результат.Вставить("addin", "name");
	Результат.Вставить("module", "name");
	Результат.Вставить("inet", "name");
	
	Возврат Новый ФиксированнаяСтруктура(Результат);
	
КонецФункции

Функция СловарьФорматированияБулевыхСвойств()
	
	ФорматOnOff = "БЛ=off; БИ=on";
	ФорматYesNo = "БЛ=no; БИ=yes";
	
	Результат = Новый Соответствие();
	
	// Свойства блокировки сеансов и заданий.
	Словарь = СловарьСвойствБлокировкиСеансовИРегламентныхЗаданий();
	Результат.Вставить(Словарь.БлокировкаСеансов, ФорматOnOff);
	Результат.Вставить(Словарь.БлокировкаРегламентныхЗаданий, ФорматOnOff);
	
	// Свойства профиля безопасности.
	Словарь = СловарьСвойствПрофиляБезопасности(Ложь);
	Результат.Вставить(Словарь.ПрофильБезопасногоРежима, ФорматYesNo);
	Результат.Вставить(Словарь.ПолныйДоступКПривилегированномуРежиму, ФорматYesNo);
	
	// Свойства виртуального каталога.
	Словарь = СловарьСвойствВиртуальногоКаталога();
	Результат.Вставить(Словарь.ЧтениеДанных, ФорматYesNo);
	Результат.Вставить(Словарь.ЗаписьДанных, ФорматYesNo);
	
	Возврат Новый ФиксированноеСоответствие(Результат);
	
КонецФункции

Функция СвойстваЭкранируемыеКавычками()
	
	Результат = Новый Соответствие();
	Результат["denied-message"] = Истина;
	Результат["permission-code"] = Истина;
	Результат["denied-parameter"] = Истина;
	Возврат Новый ФиксированноеСоответствие(Результат);
	
КонецФункции

#КонецОбласти

#КонецЕсли